package GUI_Data.FlightSeatPanel;

import Data_Flow.DataOperator;
import Data_Flow.GetData;
import Data_Structure.DataImplement.Flight;
import Data_Structure.DataImplement.SeatClassAndPrice;

import javax.swing.*;
import java.awt.*;



/**
 * The AirbusA320 panel of seat choosing.
 * The main frame will generate this class as seat choose panel according to the reservation.
 * @author Xiaorun Wang
 * @since 9 April 2022
 * @version 1.0
 */
public class AirbusA320Panel extends FlightSeatPanel {
    private GetData getData;
    private DataOperator dataOperator;
    /**
     * The plane type of this panel
     */
    private Flight.PlaneType planeType = Flight.PlaneType.AirbusA320;

    /**
     * The main frame. Used to create a confirm dialog only.
     */
    private JFrame mainFrame;

    /**
     * The number of rows of class A seats.
     */
    private static final int seatsARow = 4;

    /**
     * The number of columns of class A seats.
     */
    private static final int seatsAColumn = 2;

    /**
     * The number of rows of class B seats.
     */
    private static final int seatsBRow = 7;

    /**
     * The number of columns of class B seats.
     */
    private static final int seatsBColumn = 3;

    //The arrays may could be removed.
    /**
     * The array of class A seatButton. Used for iterating over all the class A seatButtons
     */
    private SeatButton[] seatsA;

    /**
     * The array of class B seatButton. Used for iterating over all the class B seatButtons
     */
    private SeatButton[] seatsB;

    /**
     * The panel used to contain all the classA seatButtons.
     */
    private JPanel panelA;

    /**
     * The panel used to contain all the classB seatButtons.
     */
    private JPanel panelB;

    /**
     * The seat class in the reservation.
     */
    private String seatClass;

    /**
     * The seatButton selected now.
     */
    private SeatButton targetButton;

    /**
     * The seatButton confirmed to be selected last time.
     */
    private SeatButton targetButtonBackup;

    /**
     * The constructor of this class.
     * Define the length and width of the panel and add components to it.
     * @param mainFrame The main frame which generated this panel.
     */
    public AirbusA320Panel(JFrame mainFrame,GetData getData){
        this.mainFrame = mainFrame;
        this.getData = getData;
        init();
        switch (seatClass){
            case "ClassA" -> this.add(panelA);
            case "ClassB" -> this.add(panelB);
        }
    }

    public AirbusA320Panel(JFrame mainFrame,GetData getData,int noUse){
        this.mainFrame = mainFrame;
        this.getData = getData;
        init();
        this.add(panelA);
    }

    /**
     * Add all the seatButtons to the related panel in this panel.
     * Will be called in the generator of this class.
     */
    private void init(){
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        double screenWidth = screenSize.getWidth();
        double screenHeight = screenSize.getHeight();
        int centerHeight = (int)(screenHeight * 2);
        int centerWidth = (int)(screenWidth * 0.2);
        Dimension centerDimension = new Dimension(centerWidth,centerHeight);
        this.setPreferredSize(centerDimension);
        panelA = new JPanel(new GridLayout(seatsARow, 5));
        panelB = new JPanel(new GridLayout(seatsBRow, 5));
        this.setLayout(new GridLayout(3,1));
        seatClass = getData.getMySeatClass();
        //seatClass = getSeatClass();
        seatsA = new SeatButton[seatsARow*seatsAColumn];
        seatsB = new SeatButton[seatsBRow*seatsBColumn];
        for (int row = 0; row < seatsARow; row++) {
            for (int column = 0; column < seatsAColumn; column++) {
                if (column == 0){
                    seatsA[row * seatsAColumn + column] = new SeatButton((row + 1) + "","A", SeatClassAndPrice.AirbusA320SeatClass[0], this,getData,dataOperator);
                    panelA.add(new JLabel());
                }
                else
                    seatsA[row * seatsAColumn + column] = new SeatButton((row + 1) + "","B",SeatClassAndPrice.AirbusA320SeatClass[0], this,getData,dataOperator);
                panelA.add(seatsA[row * seatsAColumn + column]);
                panelA.add(new JLabel());
            }
        }
        for (int row = 0; row < seatsBRow; row++) {
            for (int column = 0; column < seatsBColumn; column++) {
                if (column == 0)
                    seatsB[row * seatsBColumn + column] = new SeatButton((row + 1) + "","C",SeatClassAndPrice.AirbusA320SeatClass[1], this,getData,dataOperator);
                else if (column == 1){
                    seatsB[row * seatsBColumn + column] = new SeatButton((row + 1) + "","D",SeatClassAndPrice.AirbusA320SeatClass[1], this,getData,dataOperator);
                    panelB.add(new JLabel());
                }
                else{
                    seatsB[row * seatsBColumn + column] = new SeatButton((row + 1) + "","E",SeatClassAndPrice.AirbusA320SeatClass[1],  this,getData,dataOperator);
                    panelB.add(new JLabel());
                }
                panelB.add(seatsB[row * seatsBColumn + column]);
            }
        }
    }

    /**
     * This method will be called when one seatButton is selected.
     * @param seatButton The seat selected.
     */
    @Override
    public void seatSelect(SeatButton seatButton){
        if (seatButton.isIfSelectable()){
            if (seatClass.equals(seatButton.getSeatClass())) {
                changeSeatColor(seatButton);
            }else {
                int n = JOptionPane.showConfirmDialog(mainFrame, "The seat class you selected is different from your reservation. The change may cause extra cost, do you still want to select this seat?",
                        "",JOptionPane.YES_NO_OPTION);
                if (n == 0){
                    changeSeatColor(seatButton);
                }
            }
        }
    }

    /**
     * To change the color of selected seatButtons now and last time.
     * Private method. Only can be called by seatSelect method.
     * @param seatButton The selected seatButton.
     */
    private void changeSeatColor(SeatButton seatButton){
        if (targetButton != null)
            targetButton.setBackground(Color.WHITE);
        if (seatButton.getBackground() == Color.WHITE) {
            seatButton.setBackground(Color.GREEN);
        } else {
            seatButton.setBackground(Color.WHITE);
        }
        targetButton = seatButton;
    }

    /**
     * To confirm the select. Only be called when the "confirm" button is selected.
     *
     * @return The selected seatButton.
     */
    @Override
    public SeatButton confirmChange(){
        if (targetButton != null){
            targetButtonBackup = targetButton;
            return targetButton;
        }else
            return null;
    }

    /**
     * To go back to last selection.
     * Will be called when cancel the selection or quit from the choose page.
     */
    @Override
    public void returnBack(){
        if (targetButtonBackup != null)
            changeSeatColor(targetButtonBackup);
        else if (targetButton != null)
            targetButton.setBackground(Color.WHITE);

    }

    /**
     * To change the color of the target button
     * @param seatButton  the target button
     */
    @Override
    public void changeButtonColor(SeatButton seatButton) {
        int row = Integer.parseInt(seatButton.getRow()) - 1;
        int column = -1;
        switch (seatButton.getSeatClass()){
            case "ClassA" -> {
                switch (seatButton.getColumn()){
                    case "A" -> column = 0;
                    case "B" -> column = 1;
                }
                targetButton = seatsA[row * seatsAColumn + column];
                targetButtonBackup = targetButton;
                targetButton.setBackground(Color.GREEN);
            }
            case "ClassB" -> {
                switch (seatButton.getColumn()){
                    case "C" -> column = 0;
                    case "D" -> column = 1;
                    case "E" -> column = 2;
                }
                targetButton = seatsB[row * seatsBColumn + column];
                targetButtonBackup = targetButton;
                targetButton.setBackground(Color.GREEN);
            }
        }

    }
}
